!pr1
On Dividing a BCD Value by 4..............Bob Sander-Cederlof

The 6502 allows two kinds of addition and subtraction operations, depending on the state of the D-bit in the status register.  After a SED (Set D) instruction, the ADC and SBC instructions will operate in decimal mode; after CLD (CLear D), ADC and SBC will operate in binary mode.

In decimal mode the range of values in a byte is from $00 to $99.  The left nybble is the ten's digit, and the right nybble is the unit's digit.  The decimal mode makes some programs much easier to write, and others more difficult.  Having both modes is nice.

In binary mode, if you want to divide by four you just shift the value right two bit-positions.  If by 8, shift 3 times.  And so on.  In decimal mode, you can very easily divide by powers of ten; however, dividing by four is more difficult.

I needed a quick way to tell if a number in decimal mode was divisible by four.  After inspecting the binary values of the decimal-mode numbers between 00 and 99 a, I found a way.  If the ten's digit is even and the unit's digit 0, 4, or 8, the number is divisible by four.  Also, if the ten's digit is odd and the unit's digit is 2 or 6, the number is divisible by four.  This can be tested as follows:

       LDA VALUE
       AND #$13
       BEQ ...     ...TEN'S EVEN, UNITS=0,4,8
       EOR #$12
       BEQ ...     ...TEN'S ODD, UNITS=2,6
       ...         ...NOT DIVISIBLE

Next I needed a way to actually divide by four.  Again I started by inspecting the various values involved.  Simply shifting right twice does not do the job, except for numbers less than ten.  You cannot even divide by two by simply shifting right once, unless the ten's digit is even.  Hmmm....  If the ten's digit is odd, I could subtract 6 frist and then shift right once to divide by two.  Doing all that twice would result in a division by four.  The subtraction must be done in binary mode, not decimal.  The subroutine below in lines 1460-1590 will divide the decimal number in VALUE by four, truncating any remainder, and return the quotient in the A-register.  Lines 1600-1700 show a shorter way to divide by two, provided you don't mind using the X-register.

To test my subroutines, I wrote some test programs.  The first program, lines 1000-1370, runs through the values 00 to 99, printing ten values to a line.  Each number that is evenly divisible by four is flagged with an asterisk.  The second program, lines 1720-1990, shows the quotient after calling DIVIDE.BCD.VALUE.BY FOUR.

I am sure there must be lots of other neat tricks possible by combining binary and decimal modes in the 6502.  Do you know some?  Send them in, and we will publish the best!
